
class User < ActiveRecord::Base
	has_many :created_events, :class_name => "Event", :foreign_key => 'creator_id', :dependent => :destroy 
	has_many :owned_events,   :class_name => "Event", :foreign_key => 'owner_id',   :dependent => :destroy 
	has_one  :right, :dependent => :destroy

  validates :email, :username, :alloted_vacation_days, :alloted_pc_days, :presence => true
  validates_uniqueness_of :email,    :message => "has already been registered", :case_sensitive => false
  validates_uniqueness_of :username, :message => "has already been registered", :case_sensitive => false

  def authorize(operation, event)
    if (event.nil? && !administrator) || !validated
      return false
    end

    if administrator
      return true
    end

    working_on_self = (id == event.owner_id)

    # Regular users do anything with site holidays
    if (event.event_type == Event::SITE_HOLIDAY && !administrator)
      return false
    end

    if (operation == Event::EDIT    && ((working_on_self && right.self_edit)    || (!working_on_self && right.other_edit    ))) ||
       (operation == Event::APPROVE && ((working_on_self && right.self_approve) || (!working_on_self && right.other_approve ))) ||
       (operation == Event::DELETE  && ((working_on_self && right.self_delete)  || (!working_on_self && right.other_delete  ))) ||
       (operation == Event::CREATE  && ((working_on_self && right.self_create)  || (!working_on_self && right.other_create  ))) 

      return true
    else
      return false
    end
  end

  def approve_event(event)
    event.approved = true
    event.approver = self
    event.save
  end

  def revoke_approval(event)
    event.approved = false 
    event.approver_id = nil 
    event.save
  end

  ####### VACATION INFO #######
  def num_vacation_days_scheduled
    vacations.reduce(0) {|sum, event| sum + event.duration}
  end

  def num_vacation_days_taken 
    vacations_taken.reduce(0) {|sum, event| sum + event.duration}
  end

  def num_vacation_days_remaining
    alloted_vacation_days - num_vacation_days_taken - num_vacation_days_scheduled
  end

  def vacations_taken
    events_taken_of_type(Event::VACATION)
  end

  def vacations
    events_of_type(Event::VACATION)
  end
  
  ####### PC VACATION INFO #######
  def num_pc_days_scheduled
    pc_vacations.reduce(0) {|sum, event| sum + event.duration}
  end

  def num_pc_days_taken 
    pc_vacations_taken.reduce(0) {|sum, event| sum + event.duration}
  end

  def num_pc_days_remaining
    alloted_pc_days - num_pc_days_taken - num_pc_days_scheduled
  end

  def pc_vacations_taken
    events_taken_of_type(Event::PC_HOLIDAY)
  end

  def pc_vacations
    events_of_type(Event::PC_HOLIDAY)
  end


  def events_taken_of_type(event_type)
    beginning_of_year = Date.new(Date.today.year)
    owned_events.where("event_type = ? AND begin_date >= ? AND end_date <= ?",
                        event_type, beginning_of_year, Date.today)
  end

  def events_of_type(event_type)
    beginning_of_year = Date.new(Date.today.year)
    end_of_year       = Date.new(Date.today.year + 1)
    owned_events.where("event_type = ? AND begin_date >= ? AND end_date < ?",
                        event_type, beginning_of_year, end_of_year)
  end

  def import_vp_events(vp_contents)
    vp_reader = VacationPlannerReader.new(vp_contents)

    vp_reader.each do |event|
      event.owner    = self
      event.creator  = self
      event.approver = self
      event.approved = true

      event.save
    end
  end
end
